/* A. Sztrajman (BsAs, April 2012)
 * Lattice BGK simple start-up code*/

#include "Common.h"
#include "Lattice.h"
#include <cmath>
#include <GL/glut.h>

int Nx = 150;
int Ny = 150;
int Nparticles = 100;
double omega = 1.2;

Lattice lattice(Nx, Ny, false, false, 1.0, omega, Nparticles);

void time_step() {
	usleep(100000);
// 	lattice.update(false);
// 	lattice.generateRandomPerturbation(0.1);
	glutPostRedisplay();
}

void display() {
	const double toDegrees = 180.0 / (4 * atan(1.0));
	glClear(GL_COLOR_BUFFER_BIT);
	glColor3ub(0, 0, 255);
	glRectd(0, - 0.05 * (Ny + 2), Nx + 2, 0);
	glRectd(0, Ny + 1, Nx + 2, (Ny + 1) * 1.05);

	double uMax = 0;
	for (int i = 0; i < Nx; i++)
		for (int j = 0; j < Ny; j++) {
			vec<double> _u = lattice.getU(i, j);
			double uMag = sqrt(pow(_u.x,2) + pow(_u.y,2));
			if (uMag > uMax)
				uMax = uMag;
		}
	if (uMax == 0) uMax = 1;
// 		uMax = 0.1;
	glColor3ub(255, 0, 0);
	for (int i = 1; i < Nx; i++)
		for (int j = 1; j < Ny; j++) {
			glPushMatrix();
			vec<double> _u = lattice.getU(i, j);
			double uMag = sqrt(pow(_u.x,2) + pow(_u.y,2));
			double scale = uMag / uMax;
			double angle = atan2(_u.y, _u.x) * toDegrees;
			glTranslated(i, j, 0);
			glScaled(scale, scale, 1);
			glRotated(angle, 0, 0, 1);
			glBegin(GL_LINES);
				glVertex2d(0, 0); glVertex2d(1, 0);
				glVertex2d(1, 0); glVertex2d(0.8, 0.2);
				glVertex2d(1, 0); glVertex2d(0.8, -0.2);
			glEnd();
			glPopMatrix();
		}
	glutSwapBuffers();
}

void reshape(int w, int h) {
	int x0 = 0, y0 = 0, dx = w, dy = h;
	double aspect = (w * (Ny + 2) * 1.1) / (h * (Nx + 2));
	if (aspect > 1) {
		dx = int(dx / aspect);
		x0 = (w - dx) / 2;
	} else {
		dy = int(dy * aspect);
		y0 = (h - dy) / 2;
	}
	glViewport(x0, y0, dx, dy);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(0, Nx + 2, - 0.05 * (Ny + 2), (Ny + 2) * 1.05);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

void mouse(int button, int state, int x, int y) {
	switch (button) {
	case GLUT_LEFT_BUTTON:
		if (state == GLUT_DOWN)
			;
		break;
	default:
		break;
	}
}

int main(int argc, char *argv[]) {
	glutInit(&argc, argv);
	if (argc > 1) {
		Nx = atoi(argv[1]);
		Ny = atoi(argv[2]);
	}
	double umax = lattice.getUMax();
//-------------------------------------------------------------
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
	glutInitWindowSize(600, 330);
	glutInitWindowPosition(100, 100);
	glutCreateWindow("Lattice Boltzmann Equation: D2Q9 Model");
	glClearColor(1.0, 1.0, 1.0, 0.0);
	glShadeModel(GL_FLAT);
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
//-------------------------MAGIA-------------------------------
	glutDisplayFunc(display);
	glutReshapeFunc(reshape);
	glutIdleFunc(time_step);
	glutMouseFunc(mouse);
	glutMainLoop();
	return 0;
}
